package com.hsource.doctorcenter.service.file.impl;

import com.aliyun.oss.OSSClient;
import com.hsource.doctorcenter.service.file.IFileService;
import com.hsource.doctorcenter.util.ErrorMsg;
import com.hsource.doctorcenter.util.OSSUtil;
import com.hsource.doctorcenter.util.RedisUtil;
import com.hsource.doctorcenter.util.StaticValue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author yangYang
 * @version 1.0
 * @date 2020/9/28 11:59
 * @describe 文件操作业务逻辑层
 */
@Service
@Slf4j
public class FileServiceImpl implements IFileService {

    @Autowired
    private OSSUtil ossUtil;
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 文件上传类型
     */
    private final static List<String> fileTypes = new ArrayList<String>(){{
        add("doc");
        add("docx");
        add("xls");
        add("xlsx");
        add("ppt");
        add("pptx");
        add("txt");
        add("md");
        add("pdf");
        add("jpg");
        add("jpeg");
        add("png");
        add("gif");
        add("bmp");
    }};


    /**
     * webstock 文件上传
     * @param request
     * @return
     * @throws IOException
     */
    @Override
    public Map<String,Object> uploadWebSockFile(MultipartHttpServletRequest request) throws IOException {
        Map<String,Object> map=new HashMap<>();
        map.put("error", ErrorMsg.SUCCESS_CODE);
        map.put("error_msg", ErrorMsg.SUCCESS_MSG);
        List<String> fileUrls=new ArrayList<>();
        File fileStream = new File(StaticValue.UPLOAD_FILEURL);
        if (!fileStream.exists()) {
            fileStream.mkdirs();
        }
        //开始上传
        MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
        List<MultipartFile> files = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> temp : multiFileMap.entrySet()) {
            files.addAll(temp.getValue());
        }
        if(files.stream().count()>9){
            map.put("error", ErrorMsg.PICTURE_LENGTH_CODE);
            map.put("error_msg", ErrorMsg.PICTURE_LENGTH_MSG);
            return map;
        }
        OSSClient client = ossUtil.getOSSClient();
        for (MultipartFile file : files){
            String fileName = file.getOriginalFilename();
            int len = fileName.lastIndexOf(".");
            String fileType1 = fileName.substring(len + 1).toLowerCase();
            if (file.isEmpty()) {
            } else {
                if(fileType1.equals("jpg")||fileType1.equals("png")||fileType1.equals("jpeg")) {
                    BigDecimal fileSize = BigDecimal.valueOf(file.getSize());
                    if (fileSize.doubleValue() > 5248000){
                        map.put("error", ErrorMsg.PICTURE_SIZE_CODE);
                        map.put("error_msg", "【" + fileName + "】" + ErrorMsg.PICTURE_SIZE_MSG);
                        return map;
                    }
                }
                String md5key = ossUtil.uploadObject2OSS(client, file);
                if(fileType1.equals("jpg")||fileType1.equals("png")||fileType1.equals("jpeg")) {
                    //图片缓存处理
                    URL url = new URL(md5key);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    // 设置超时间为3秒
                    conn.setConnectTimeout(3 * 1000);
                    // 防止屏蔽程序抓取而返回403错误
                    conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                    // 得到输入流
                    InputStream inputStream = conn.getInputStream();
                    // 获取自己数组
                    byte[] getData = readInputStream(inputStream);
                    BASE64Encoder encoder = new BASE64Encoder();
                    String uuid = UUID.randomUUID().toString().replaceAll("-","");
                    redisUtil.set("webStock-center:image:"+uuid,encoder.encode(getData).trim());
                    redisUtil.expire("webStock-center:image:"+uuid,7776000);
                    md5key="http://api.bencaoyuantang.com:9002/doctor-center/file/showImage/"+uuid;
                }
                fileUrls.add(md5key);
            }
        }
        map.put("files",fileUrls);
        return map;
    }


    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    @Override
    public Map<String,Object> uploadOssFile(MultipartHttpServletRequest request){
        Map<String,Object> map=new HashMap<>();
        map.put("error", ErrorMsg.SUCCESS_CODE);
        map.put("error_msg", ErrorMsg.SUCCESS_MSG);
        List<String> fileUrls=new ArrayList<>();
        File fileStream = new File(StaticValue.UPLOAD_FILEURL);
        if (!fileStream.exists()) {
            fileStream.mkdirs();
        }
        //开始上传
        MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
        List<MultipartFile> files = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> temp : multiFileMap.entrySet()) {
            files.addAll(temp.getValue());
        }
        if(files.stream().count()>9){
            map.put("error", ErrorMsg.PICTURE_LENGTH_CODE);
            map.put("error_msg", ErrorMsg.PICTURE_LENGTH_MSG);
            return map;
        }
        OSSClient client = ossUtil.getOSSClient();
        for (MultipartFile file : files){
            String fileName = file.getOriginalFilename();
            int len = fileName.lastIndexOf(".");
            String fileType1 = fileName.substring(len + 1).toLowerCase();
            if (file.isEmpty()) {
            } else {
                if(fileType1.equals("jpg")||fileType1.equals("png")||fileType1.equals("jpeg")) {
                    BigDecimal fileSize = BigDecimal.valueOf(file.getSize());
                    if (fileSize.doubleValue() > 5248000){
                        map.put("error", ErrorMsg.PICTURE_SIZE_CODE);
                        map.put("error_msg", "【" + fileName + "】" + ErrorMsg.PICTURE_SIZE_MSG);
                        return map;
                    }
                }
                String md5key = ossUtil.uploadObject2OSS(client, file);
                fileUrls.add(md5key);
            }
        }
        map.put("files",fileUrls);
        return map;
    }
    /**
     * 文件上传
     * @param request
     * @return
     */
    @Override
    public Map<String,Object> uploadFile(MultipartHttpServletRequest request) throws IOException {
        Map<String,Object> map=new HashMap<>();
        map.put("error", ErrorMsg.SUCCESS_CODE);
        map.put("error_msg", ErrorMsg.SUCCESS_MSG);
        List<String> fileUrls=new ArrayList<>();
        File fileStream = new File(StaticValue.UPLOAD_FILEURL);
        if (!fileStream.exists()) {
            fileStream.mkdirs();
        }
        //开始上传
        MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
        List<MultipartFile> files = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> temp : multiFileMap.entrySet()) {
            files.addAll(temp.getValue());
        }
        if(files.stream().count()>9){
            map.put("error", ErrorMsg.PICTURE_LENGTH_CODE);
            map.put("error_msg", ErrorMsg.PICTURE_LENGTH_MSG);
            return map;
        }
        BufferedOutputStream stream;
        for (MultipartFile file : files){
            if (file.isEmpty()) {
            }else{
                //获取文件属性
                String fileName = file.getOriginalFilename();
                BigDecimal fileSize = BigDecimal.valueOf(file.getSize());
                if(fileSize.doubleValue()>5248000){
                    map.put("error", ErrorMsg.PICTURE_SIZE_CODE);
                    map.put("error_msg","【"+fileName+"】"+ ErrorMsg.PICTURE_SIZE_MSG);
                    return map;
                }
                int len = fileName.lastIndexOf(".");
                if (len > 0) {
                    String fileType1 = fileName.substring(len + 1).toLowerCase();
                    if (fileTypes.contains(fileType1)) {
                        String name = fileName.substring(0, len);
                        String fileType = fileName.substring(len + 1);
                        String physicalName =(new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date()) + "." + fileType;
                        String path =  physicalName;
                        byte[] bytes = file.getBytes();
                        stream = new BufferedOutputStream(new FileOutputStream(new File(StaticValue.UPLOAD_FILEURL + "/" + physicalName)));
                        stream.write(bytes);
                        stream.close();
                        fileUrls.add(StaticValue.UPLOAD_FILEURL + "/" + physicalName);
                    }
                }
            }
        }
        map.put("files",fileUrls);
        return map;
    }
}
